package com.asiainfo.iam.service;


import com.asiainfo.iam.constant.VerificationConstant;
import com.asiainfo.iam.controller.DMDatabaseOperateController;
import com.asiainfo.iam.controller.HTTPRequestController;
import com.asiainfo.iam.tool.ProgressBarDrawer;
import com.asiainfo.iam.tool.VerifyUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;


@Service
public class SignatureVerificationService {
    private static final Logger log = LoggerFactory.getLogger(SignatureVerificationService.class);

    @Autowired
    private HTTPRequestController httpRequestController;

    @Autowired
    private DMDatabaseOperateController dmDatabaseOperateController;
    @Autowired
    private ProgressBarDrawer progressBarDrawer;

    @Autowired
    private VerifyUtil verifyUtil;


    /**
     * 签名
     */
    public void queryTableContentQianMing(String databaseName,
                                          String tableName,
                                          Connection connection,
                                          List<String> findNameList,
                                          List<String> columnNameList) {
        // 初始化当前行数计数器，用于跟踪数据处理进度
        long nowRowCount = 0L;
        long sum = 0L;

        // 构建查询字段和缓存
        HashSet<String> cache = new HashSet<>();

        // 初始化StringBuilder用于拼接查询字段和构建条件语句
        StringBuilder findNameString = new StringBuilder();
        StringBuilder conditionTemp = new StringBuilder();

        // 遍历 findNameList，将字段名拼接到 SQL 查询字符串，并缓存到集合中用于后续处理
        for (String columName : findNameList) {
            findNameString.append(columName).append(",");
            cache.add(columName);
        }

        // 遍历 columnNameList，将字段名拼接到 SQL 查询字符串，并构建条件语句
        for (String columName : columnNameList) {
            if (!cache.contains(columName)) {
                findNameString.append(columName).append(",");
                conditionTemp.append(" AND ").append(columName).append(" IS NOT NULL");
            }
        }

        findNameString.deleteCharAt(findNameString.length() - 1); // 删除最后一个逗号


        // 查询表行数
        long tableRowCount = dmDatabaseOperateController.queryTableRowSum(databaseName, tableName, connection, conditionTemp.toString());

        // 构建查询语句
        String sqlQuery = "SELECT " + findNameString + " FROM " + databaseName.toUpperCase() + "." + tableName + " WHERE 1=1" + conditionTemp;


        // 创建 Statement 对象
        try (Statement statement = connection.createStatement();
             ResultSet resultSet = statement.executeQuery(sqlQuery)) {

            // 处理结果集
            while (resultSet.next()) {
                ++nowRowCount;
                // 调用进度条绘制方法,看结果处理进度
                progressBarDrawer.callProgressBar(tableRowCount, nowRowCount);

                // 初始化 valueSQL 列表，用于存储从结果集中获取的字段值
                List<String> valueSQL = new LinkedList<>();

                // 获取 findNameList 中字段的值
                for (String base64EncodedString : findNameList) {
                    String columnName = resultSet.getString(base64EncodedString);
                    valueSQL.add(columnName);
                }

                // 拼接 columnNameList 中字段的值
                StringBuilder concatenatedString = new StringBuilder();
                for (String columnName : columnNameList) {
                    String column = resultSet.getString(columnName);
                    concatenatedString.append(column);
                }

                //
                // 将拼接的字符串数据转换为 Base64 编码，用于后续签名请求
                String base64EncodedString = Base64.getEncoder().encodeToString(concatenatedString.toString().getBytes());

                // 发送 HTTP 请求签名
//                HashMap<String, String> httpRequest = httpRequestController.sendHttpRequestQianMing(base64EncodedString);

                //自研签名算法
                HashMap<String, String> signature = verifyUtil.generateSignature(base64EncodedString);
                // 更新签名字段
                sum += dmDatabaseOperateController.updateB64SignedDataColumn(
                        databaseName,
                        tableName,
                        connection,
                        findNameList,
                        valueSQL,
                        signature.get(VerificationConstant.B64SD));
                dmDatabaseOperateController.updateB64CertColumn(
                        databaseName,
                        tableName,
                        connection,
                        findNameList,
                        valueSQL,
                        signature.get(VerificationConstant.B64CERT));
            }
        } catch ( SQLException e) {
            log.error("发生 SQLException 异常: {}", e.getMessage(), e);
            throw new RuntimeException(e);
        } catch (Exception e) {
            log.error("发生未知异常: {}", e.getMessage(), e);
            throw new RuntimeException(e);
        }finally {
            System.out.println();
            System.out.println("***************************");
            System.out.println("         执行结束");
            System.out.println("数据库名称：" + databaseName);
            System.out.println("数据表名称：" + tableName);
            System.out.println("影响条数：" + sum);
        }



    }




    /**
     * 执行前端验签操作，将数据发送至验签服务，并根据结果更新数据库状态。
     * @param databaseName 数据库名称
     * @param tableName 表名称
     * @param connection 数据库连接
     * @param findNameList 查询字段列表
     * @param columnNameList 需要拼接验证的字段列表
     */
    public void queryTableContentYanQian(String databaseName, String tableName, Connection connection, List<String> findNameList, List<String> columnNameList) {
        long nowRowCount = 0L;
        long sum = 0L;

        HashSet<String> cache = new HashSet<>();


        StringBuilder findNameString = new StringBuilder();
        StringBuilder conditionTemp = new StringBuilder();

        // 构建查询字段和缓存
        for (String columName : findNameList) {
            findNameString.append(columName).append(",");
            cache.add(columName);
        }

        // 构建条件字段和 WHERE 子句
        for (String columName : columnNameList) {
            if (!cache.contains(columName)) {
                findNameString.append(columName).append(",");
                conditionTemp.append(" AND ").append(columName).append(" IS NOT NULL");
            }
        }


        // 查询表行数
        long tableRowCount = dmDatabaseOperateController.queryTableRowSum(databaseName, tableName, connection, conditionTemp.toString());
        // 构建查询字段
        findNameString.append("b64SignedData,b64Cert");
        // 构建查询 SQL
        String sqlQuery = "SELECT " + findNameString + " FROM " + databaseName.toUpperCase() + "." + tableName + " WHERE 1=1" + conditionTemp;
        // 创建 Statement 对象
        try (Statement statement = connection.createStatement();
             // 执行 SQL 语句
             ResultSet resultSet = statement.executeQuery(sqlQuery)) {
            // 遍历结果集
            while (resultSet.next()) {
                // 获取结果集中的数据
                ++nowRowCount;
                // 调用进度条绘制方法
                progressBarDrawer.callProgressBar(tableRowCount, nowRowCount);
                // 创建一个 List 对象，用于存储结果集中的数据
                List<String> valueSQL = new LinkedList<>();

                // 获取 findNameList 中字段的值
                for (String base64EncodedString : findNameList) {
                    // 获取字段的值
                    String columName = resultSet.getString(base64EncodedString);
                    valueSQL.add(columName);
                }

                // 拼接 columnNameList 中字段的值
                StringBuilder concatenatedString = new StringBuilder();
                for (String columnName : columnNameList) {
                    String column = resultSet.getString(columnName);
                    concatenatedString.append(column);
                }

                String base64EncodedString = Base64.getEncoder().encodeToString(concatenatedString.toString().getBytes());

//                // 发送 HTTP 请求验签
//                long httpRequest = httpRequestController.sendHttpRequestYanQian(
//                        base64EncodedString,
//                        resultSet.getString(VerificationConstant.B64SD),
//                        resultSet.getString(VerificationConstant.B64CERT));

                //自研算法
                long verify = verifyUtil.verifySignature(base64EncodedString, resultSet.getString(VerificationConstant.B64SD));
                // 更新数据库状态
                if (verify == 0) {
                    sum += dmDatabaseOperateController.updateTableColumnYanQian(
                            databaseName,
                            tableName,
                            connection,
                            findNameList,
                            valueSQL, "验签成功");
                } else {
                    sum += dmDatabaseOperateController.updateTableColumnYanQian(
                            databaseName,
                            tableName,
                            connection,
                            findNameList,
                            valueSQL, "验签失败");
                }
            }
        } catch ( SQLException e) {
            log.error("发生 SQLException 异常: {}", e.getMessage(), e);
            throw new RuntimeException(e);
        } catch (Exception e) {
            log.error("发生未知异常: {}", e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            System.out.println();
            System.out.println("***************************");
            System.out.println("         执行结束");
            System.out.println("数据库名称：" + databaseName);
            System.out.println("数据表名称：" + tableName);
            System.out.println("影响条数：" + sum);
        }

    }
}
